#ifndef MODEL_H
#define MODEL_H

#include "IAbstract_subject.h"
#include "configuration.h"
#include "common/parameters.h"
#include "common/exceptions.h"
#include "project.h"

#include <QVector>
#include <QString>
#include <QBitArray>
#include <QPair>

class Uav_Joined_Wings;

struct model_state
{
    bool draw_simulation;      // if needs to draw the simulation
    float st_scale;            // the scale number for the points of the simulation.
    int total_steps;           // the total steps of the simulation.
    int st_step;               // the current steps of the simulation to draw
    bool c_texture;            // if the configuration will be drawn with texture
    bool s_texture;            // if the configuration will be drawn with texture
    bool to_load_simulation;   // if needs to load the simulation information
    int cdrawed_configuration; // the last configuration that was drawn
    QString c_path;            // the current path of the current configuration.
};

class Model : public IAbstract_subject
{
public:
  Model();
  ~Model();
  void subscribe(IAbstract_observer *);
  void unsubscribe(IAbstract_observer *);
  void initialize_state();
  void create_project(const QString &file_directory, const QString &filename);
  void open_project(const QString &project_name, int nconfig);
  const Project& current_project() const;
  inline void set_analysis_parameters(QVector<QPair<QString, QString> *> &parameters) {interval_parameters = parameters;}
  inline const QVector<QPair<QString, QString> *> &get_analysis_parameters() {return interval_parameters;}
  void make_configurations(QVector<Parameters *> configs_params, Airfoils_curve_map * airfoils, int module);
  void draw_configuration(int config, int s_step = 0, float scale = 0.5) throw (Non_Existent_Geometry);
  void generate_configurations();
  bool is_allc_generated();
  inline const model_state &get_state() const {return _state;}
  inline int total_configurations() const {return configurations.size();}
  void c_simulated(int configuration);
  bool is_allc_simulated();
  void load_simulation(int configuration, int total_steps, double scale);
  void add_simulation_zones(int, QVector<time_zone*>);
  void clean_model();
  const Configuration &get_configuration(int index) const;

private:
  Project *c_project;  // the current project object
  QVector<IAbstract_observer *> observers; // the list of the model observers
  QVector<Configuration *> configurations; // the configurations
  QBitArray loaded_simulations; // if the simulation data need to load
  QBitArray configuration_simulated;
  model_state _state; // the model state
  QVector<QPair<QString, QString> *> interval_parameters;
};

#endif // MODEL_H
